
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include <vector>

// 服务 UUID
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
// 接收数据特征 UUID
#define CHARACTERISTIC_RX_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
// 发送数据特征 UUID
#define CHARACTERISTIC_TX_UUID "c0c5483e-36e1-4688-b7f5-ea07361b26a8"

// 服务端连接/断开连接回调类
class MyServerCallbacks : public BLEServerCallbacks
{
  void onConnect(BLEServer *pServer)
  {
    Serial.println("客户端已连接");
  }
  void onDisconnect(BLEServer *pServer)
  {
    Serial.println("客户端已断开连接");
    // 重新开始广播，以便新的客户端可以连接
    BLEDevice::startAdvertising();
  }
};

// 特征写入回调类
class MyCharacteristicCallbacks : public BLECharacteristicCallbacks
{
  BLECharacteristic *pTxCharacteristic;

public:
  MyCharacteristicCallbacks(BLECharacteristic *txChar) : pTxCharacteristic(txChar) {}
  void onWrite(BLECharacteristic *pCharacteristic)
  {
    std::string value = pCharacteristic->getValue();
    Serial.print("接收到的数据: ");
    for (char c : value)
    {
      Serial.printf("%02X ", (unsigned char)c);
    }
    Serial.println();
    Serial.println();

    // 将接收到的数据转换为16进制形式
    std::vector<uint8_t> hexData;
    for (char c : value)
    {
      hexData.push_back(static_cast<uint8_t>(c));
    }

    // 设置要返回的16进制数据
    pTxCharacteristic->setValue(hexData.data(), hexData.size());
    pTxCharacteristic->notify();
  }
};

void initble()
{
  Serial.begin(115200);
  // 初始化 BLE 设备
  BLEDevice::init("ESP32_BLE_Server");

  // 创建 BLE 服务器
  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  // 创建 BLE 服务
  BLEService *pService = pServer->createService(SERVICE_UUID);

  // 创建接收数据的特征
  BLECharacteristic *pRxCharacteristic = pService->createCharacteristic(
      CHARACTERISTIC_RX_UUID,
      BLECharacteristic::PROPERTY_WRITE);
  // 创建发送数据的特征
  BLECharacteristic *pTxCharacteristic = pService->createCharacteristic(
      CHARACTERISTIC_TX_UUID,
      BLECharacteristic::PROPERTY_NOTIFY);
  pTxCharacteristic->addDescriptor(new BLE2902());

  // 设置接收数据特征的回调函数，并传入发送数据特征的指针
  pRxCharacteristic->setCallbacks(new MyCharacteristicCallbacks(pTxCharacteristic));

  // 启动服务
  pService->start();

  // 开始广播
  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();

  Serial.println("BLE 服务已启动，等待客户端连接...");
}
